<script lang="ts">
export default {
  name: "xt-search-bar",
};
</script>

<script setup lang="ts">
import xtForm from "../../../components/xt-form/src/main.vue";
import xtFormItem from "../../../components/xt-form-item/src/main.vue";
import xtRow from "../../../components/xt-row/src/main.vue";
import xtCol from "../../../components/xt-col/src/main.vue";
import { componentSizeMap } from "element-plus";

import { computed, onMounted, ref } from "vue";
import Typings from "../../../../typings";

interface Props {
  collapse?: boolean;
  labelWidth?: number | string;
  size?: Typings.Common.size;
  data: Typings.Common.plainObj;
  formJson: Typings.SearchBar.JsonType[];
}

const sizeHeight = {
  collapse: true,
  small: componentSizeMap.small,
  defaut: componentSizeMap.default,
  large: componentSizeMap.large,
};

const props = withDefaults(defineProps<Props>(), {
  labelWidth: 96,
  size: "default",
  data: () => ({}),
  formJson: () => [],
});

const emit = defineEmits(["search", "reset", "update:data"]);

// 表单实例
const formIns = ref();

// 收缩|展开按钮信息
const collapseObj = {
  collapse: ref(false),
  name: computed(() => {
    return collapseObj.collapse.value ? "收缩" : "展开";
  }),
  init() {
    if (formObj.getFormJson.value.length > 3 && props.collapse) {
      collapseObj.collapse.value = true;
    } else {
      collapseObj.collapse.value = false;
    }
  },
  toggle() {
    collapseObj.collapse.value = !collapseObj.collapse.value;
  },
};

// 表单项信息
const formObj = {
  getFormJson: computed(() => {
    return props.formJson.filter((json) => !json.isHide);
  }),

  // 获取过滤后最终展示的表单项
  getFinalFormJsons: computed(() => {
    const jsons = props.formJson.filter(
      (json) => !(json?.isHide && json.isHide())
    );

    if (jsons.length > 3 && collapseObj.collapse.value) {
      return jsons.filter((_json, index) => index < 3);
    }

    return jsons;
  }),
};

// 按钮操作列信息
const handleObj = {
  search() {
    emit("search", props.data);
  },
  reset() {
    formIns.value.instance.resetFields();
    emit("search", props.data);
  },
  span: computed(() => {
    const len = formObj.getFinalFormJsons.value.length;
    const mod = 3 - (len % 3);
    return mod * 8;
  }),
};

onMounted(() => {
  collapseObj.init();
});
</script>

<template>
  <xt-form
    ref="formIns"
    class="xt-search-bar"
    :labelWidth="labelWidth"
    :size="size"
    :model="data"
  >
    <xt-row :gutter="24">
      <xt-col
        :span="span || 8"
        v-for="{ el, span, label, prop, options, on = {}, ...col } in formObj
          .getFinalFormJsons.value"
        :key="prop"
      >
        <xt-form-item :label="label" :prop="prop">
          <template v-if="['input'].includes(el)">
            <xt-input
              v-model="data[prop]"
              v-bind="{ ...col }"
              v-on="on"
            ></xt-input>
          </template>

          <template v-if="['select'].includes(el)">
            <xt-select
              v-model="data[prop]"
              :options="options"
              v-bind="{ ...col }"
              v-on="on"
            ></xt-select>
          </template>

          <template v-if="['cascader'].includes(el)">
            <xt-cascader
              v-model="data[prop]"
              :options="options"
              v-bind="{ ...col }"
              v-on="on"
            />
          </template>

          <template v-if="['date-picker'].includes(el)">
            <xt-date-picker
              v-model="data[prop]"
              v-bind="{ ...col }"
              v-on="on"
            />
          </template>

          <template v-if="['slot'].includes(el)">
            <slot :name="prop"></slot>
          </template>
        </xt-form-item>
      </xt-col>
      <xt-col :span="handleObj.span.value">
        <div
          class="btn-container"
          :style="{ lineHeight: sizeHeight[props.size || 'default'] }"
        >
          <xt-link class="btn" @click="handleObj.search">查询</xt-link>
          <xt-link class="btn" @click="handleObj.reset" type="info"
            >重置</xt-link
          >
          <xt-link
            class="btn"
            type="info"
            @click="collapseObj.toggle"
            v-if="formObj.getFormJson.value.length > 3"
            >{{ collapseObj.name }}</xt-link
          >
        </div>
      </xt-col>
    </xt-row>
  </xt-form>
</template>

<style lang="scss">
@use "../../../scss/xt-search-bar.scss";
</style>
